using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Box2D.XNA;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Devices.Sensors;
using ShakeGestures;

namespace Elementum
{
    public enum PlayerState
    {
        Left,
        Right,
        Climb
        //Stand_Left,
        //Stand_Right
    }
    public class Player : Actor, Controlable
    {
        //protected PlayerCollisionDetector _collision;
        protected float _speed = 2.5f;
        Animation _walk_r;
        Animation _stand;
        Animation _jump;


        Body _buttonbody;

        public List<ElementPiece> elementPieceList = new List<ElementPiece>();

        public PlayerState _playerState;

        public Player(World world, Stage stage)
            : base(world, stage)
        {
            _walk_r = new Animation("images/player/player",new Rectangle(48, 0, 336, 60), new Point(48, 60));
            _walk_r.DeltaTime = 80;
            //_walk_r = new Animation("images/player/walk_r", new Point(48, 56));
            _stand = new Animation("images/player/player",new Rectangle(0, 0, 0, 60), new Point(48, 60));
            _jump = new Animation("images/player/player", new Rectangle(288, 0, 0, 60), new Point(48, 60));
            _playerState = new PlayerState();

            CurrentAnimation = _stand;
            Size = new Vector2(CurrentAnimation.FrameSize.X - 10, CurrentAnimation.FrameSize.Y);
            _body.SetFixedRotation(true);

            _body._userData = "player";

            _contactDetector = new PlayerCollisionDetector(this._body);
            BeginContact += _contactDetector.BeginContact;
            EndContact += _contactDetector.EndContact;

            if (StageManager.Save.StageStateTable[StageManager.CurrentStateID].PlayerPosition != null)
            {
                Position = StageManager.Save.StageStateTable[StageManager.CurrentStateID].PlayerPosition;
            }

            ShakeGesturesHelper.Instance.ShakeGesture += Instance_ShakeGesture;
            //  new EventHandler<ShakeGestureEventArgs>(Instance_ShakeGesture);
            ShakeGesturesHelper.Instance.MinimumRequiredMovesForShake = 4;
            ShakeGesturesHelper.Instance.Active = true;

        }


        protected override void SetSize(Vector2 size)
        {
            _size = size;
            {
                FixtureDef f = new FixtureDef();
                PolygonShape p = new PolygonShape();

                f.shape = p;
                f.density = 20;//20
                f.restitution = 0.0001f;//0.01
                f.friction = 0.5f;//0.5
                //p.SetAsBox(_size.X / (PIXEL_TO_METER * 2), _size.Y / (PIXEL_TO_METER * 2));
                //_body.CreateFixture(f);

                Vector2[] vertices = new Vector2[6];
                vertices[0] = new Vector2(-20, 28) / PIXEL_TO_METER;
                vertices[1] = new Vector2(-20, -26) / PIXEL_TO_METER;
                vertices[2] = new Vector2(-18, -28) / PIXEL_TO_METER;
                vertices[3] = new Vector2(18, -28) / PIXEL_TO_METER;
                vertices[4] = new Vector2(20, -26) / PIXEL_TO_METER;
                vertices[5] = new Vector2(20, 28) / PIXEL_TO_METER;
                p.Set(vertices, 6);

                this._fixture = _body.CreateFixture(f);

            }
            _fixture.SetFilterData(ref _filter);
        }

        public override void CreatBody(World world)
        {
            base.CreatBody(world);
            // _body.SetType(BodyType.Static);
        }

        public Vector2 IniPosition
        {
            get
            {
                return _iniPosition;
            }
            set
            {
                _iniPosition = value;
                Position = value;
                if (StageManager.Save.StageStateTable[StageManager.CurrentStateID].PlayerPosition != Vector2.Zero)
                {
                    Position = StageManager.Save.StageStateTable[StageManager.CurrentStateID].PlayerPosition;
                }
            }
        }

        private void Instance_ShakeGesture(object sender, ShakeGestureEventArgs e)
        {

            // shake = true;
        }


        public float testX
        {
            get;
            set;
        }

        protected override void ConfigFilter()
        {
            base.ConfigFilter();
            _filter.categoryBits = PlayerCategory;
            _filter.maskBits = PlayerMask;
        }

        public PlayerCollisionDetector CollisionListener
        {
            get
            {
                if (_contactDetector == null)
                    throw new Exception("null _contactDetector");
                return (PlayerCollisionDetector)_contactDetector;
            }
        }

        public override void Update(int delta)
        {

           // _body.SetAngularVelocity
            base.Update(delta);
            CurrentAnimation.LayerDepth = 0.5f;
            //CurrentAnimation.IsReplay = true;
            CurrentAnimation.DrawEffect = SpriteEffects.None;
            if (Math.Abs(_body.GetLinearVelocity().X) < _speed && Math.Abs(_body.GetLinearVelocity().Y)<0.5f)
                if(_body.GetType()!=BodyType.Static)
                CurrentAnimation = _stand;
            ThrowOutElement();
            if (_playerState == PlayerState.Left)
                CurrentAnimation.DrawEffect = SpriteEffects.FlipHorizontally;
            else
                CurrentAnimation.DrawEffect = SpriteEffects.None;

            if (elementPieceList.Count() > 0 && ActionEventCount == 0 && ModifierContainer == null)
            {
                GameStage.ActionButtom.Enable = true;
                GameStage.ActionButtom.CurrentAnimation = GameStage.ActionButtom._button;
            }

        }

        public void Left()
        {
            PlayerCollisionDetector con = CollisionListener;
            if (con.leftlList.Count() == 0 && _isLive)
            {
                _playerState = PlayerState.Left;
                CurrentAnimation = _walk_r;
                CurrentAnimation.DrawEffect = SpriteEffects.FlipHorizontally;
                _body.SetLinearVelocity(new Vector2(-_speed, _body.GetLinearVelocity().Y));
            }
        }

        public void Right()
        {
            PlayerCollisionDetector con = CollisionListener;
            if (con.rightList.Count() == 0 && _isLive)
            {
                _playerState = PlayerState.Right;
                CurrentAnimation = _walk_r;
                CurrentAnimation.DrawEffect = SpriteEffects.None;
                _body.SetLinearVelocity(new Vector2(_speed, _body.GetLinearVelocity().Y));
            }
        }

        public void Jump()
        {
            //throw new NotImplementedException();
            //_playerState = PlayerState.Jump;
            CurrentAnimation = _jump;

            PlayerCollisionDetector con = CollisionListener;
            if (con.buttonList.Count() != 0 && _isLive)
                _body.SetLinearVelocity(new Vector2(_body.GetLinearVelocity().X, 5));
        }

        public override void Action(VisibleObject owner, TouchLocationState state)
        {
            base.Action(owner,state);
            if (ActionEventCount == 0 && state == TouchLocationState.Pressed)
                shake = true;
        }

        public void KillPlayer()
        {
            if (_isLive)
            {
                _isLive = false;
                ModifierContain modiCon = new ModifierContain(this);
                RotationModifier rotaModi = new RotationModifier(0, 90 * PI / 180, 10, 50);
                AlphaModifier alphaModi = new AlphaModifier(1, 0.01f, 10, 55);
                modiCon.AddModifier(rotaModi);
                modiCon.AddModifier(alphaModi);
                alphaModi.ModifyDoneAction += AfterDeadAnimaion;
                this.ModifierContainer = modiCon;
            }
        }

        public override void BeginContactAction(Contact contact, Body contactBody, float normal)
        {
            base.BeginContactAction(contact, contactBody, normal);
            if (contactBody._userData == "killBund")
            {
                if (_isLive)
                {
                    _isLive = false;
                    ModifierContain modiCon = new ModifierContain(this);
                    RotationModifier rotaModi = new RotationModifier(0, 90 * PI / 180, 10, 50);
                    AlphaModifier alphaModi = new AlphaModifier(1, 0.01f, 10, 55);
                    modiCon.AddModifier(rotaModi);
                    modiCon.AddModifier(alphaModi);
                    alphaModi.ModifyDoneAction += AfterDeadAnimaion;
                    this.ModifierContainer = modiCon;
                }
                // 
                //Jump();
            }
        }

        public void AfterDeadAnimaion()
        {
            this.ModifierContainer = null;
            Alpha = 1;
            Kill();
        }

        public override void EndContactAction(Contact contact, Body contactBody, float normal)
        {
            base.EndContactAction(contact, contactBody, normal);

        }

        public override void Kill()
        {
            base.Kill();

            if (!_isLive)
            {
                //IniPosition = _iniPosition;
                Position = IniPosition;
                _isLive = true;
                GameStage.Restart();
            }
        }

        public bool shake = false;

        //public override void Action(TouchLocationState state)
        //{
        //    base.Action(state);
        //        Action(state);
        //}

        public void ThrowOutElement()
        {
            if (shake)
            {
                if (elementPieceList.Count > 0)
                {
                    testX += 1;
                    elementPieceList[elementPieceList.Count - 1].ThrowOutItem();
                    elementPieceList.Remove(elementPieceList[elementPieceList.Count - 1]);

                }
                shake = false;
                if (elementPieceList.Count == 0)
                {
                    GameStage.ActionButtom.Enable = false;
                    GameStage.ActionButtom.CurrentAnimation = null;
                }

            }
        }

    }
}
